#include "ftp.h"

int get_cmd_type(char *data){
	
	if(!strcmp(data,"ls"))   return LS;
	if(!strcmp(data,"pwd"))   return PWD;
	if(!strcmp(data,"quit"))   return QUIT;

	if(strstr(data,"cd") != NULL) return CD;
	if(strstr(data,"get") != NULL) return GET;
	if(strstr(data,"put") != NULL) return PUT;

	return -1;

}


char *GetDir(char *data){

	char *p;
	p = strtok(data," ");
	p = strtok(NULL," ");

	return p;
}

void msg_handler(struct Msg msg,int fd){
	
	int ret,filefd;
	char buf[1024];
	char *file = NULL;

	ret = get_cmd_type(msg.data);
	switch(ret){

		case LS:
		case PWD:{
			FILE *r = popen(msg.data,"r");
			fread(msg.data,sizeof(msg.data),1,r);
			write(fd,&msg,sizeof(msg));
			pclose(r);
			break;
		}
		case QUIT:
			printf("client quit!\n");
			break;
		case CD:{
			char *dir = GetDir(msg.data);
			chdir(dir);
			break;
		}
		case PUT:
			filefd = open(GetDir(msg.data),O_RDWR|O_CREAT,0666);
			write(filefd,msg.context,strlen(msg.context));
			close(filefd);
			break;
		case GET:
			file = GetDir(msg.data);
			filefd = open(file,O_RDWR);
			if(filefd == -1){
				strcpy(msg.data,"No this file!\n");
				break;
			}
			else if(filefd > 0){
				int n_read = read(filefd,buf,sizeof(buf));
				close(filefd);
				printf("client read %d characters\n",n_read);
				strcpy(msg.data,buf);
				write(fd,&msg,sizeof(struct Msg));
			}
			break;
		}
	return ;
}

int main(int argc,char **argv){

	int ret;
	int sfd;
	int cfd;
	socklen_t c_addr_len;
	pid_t pid;
	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;
	struct Msg msg;

	if(argc != 2){
		
		perror("param is not right!\n");
		exit(-1);
	}
	
	bzero(&s_addr,sizeof(struct sockaddr_in));
	bzero(&c_addr,sizeof(struct sockaddr_in));

	//1. socket
	sfd = socket(AF_INET,SOCK_STREAM,0);

	//2. bind	
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(atoi(argv[1]));
	s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(sfd,(struct sockaddr *)&s_addr,sizeof(s_addr));

	//3. litsen
	listen(sfd,10);

	//4. aceept
	c_addr_len = sizeof(c_addr);
	while(1){
		cfd = accept(sfd,(struct sockaddr *)&c_addr,&c_addr_len);
		pid = fork();
		if(cfd == -1){
			perror("accept");
			exit(0);
		}

		if(pid == 0){
			close(sfd);
			break;
		}
		else if(pid > 0){
			close(cfd);
		}
		else{
			perror("pid error");
		}
	}
	if(pid == 0){
		while(1){
			bzero(msg.data,sizeof(msg.data));
			int n_read = read(cfd,&msg,sizeof(msg));
			if(n_read == 0){
				printf("client out\n");
				close(cfd);
				break;
			}
			else if(n_read > 0){
				msg_handler(msg,cfd);
			}			
		}
	}
	return 0;
}
